View Javadoc
1 /* ==================================================================== 2 * Bigyo Software License, version 1.1 3 * 4 * Copyright (c) 2004, Zsombor Gegesy. All rights reserved. 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. Neither the name of the Bigyo Group nor the name "Bigyo" nor 18 * the names of its contributors may be used to endorse or promote 19 * products derived from this software without specific prior 20 * written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 * 35 * ==================================================================== 36 */ 37 38 package net.sf.bigyo.container.ant; 39 40 import java.io.BufferedWriter; 41 import java.io.File; 42 import java.io.FileWriter; 43 import java.io.IOException; 44 import java.util.ArrayList; 45 import java.util.Iterator; 46 import java.util.List; 47 import java.util.Map; 48 import java.util.Properties; 49 50 import net.sf.bigyo.api.ContainerException; 51 import net.sf.bigyo.container.ClassDependency; 52 import net.sf.bigyo.container.ComponentDescription; 53 import net.sf.bigyo.container.Kernel; 54 import net.sf.bigyo.container.Main; 55 import net.sf.bigyo.container.api.Constants; 56 57 import org.apache.avalon.fortress.util.dag.CyclicDependencyException; 58 import org.apache.log4j.BasicConfigurator; 59 import org.apache.tools.ant.BuildException; 60 import org.apache.velocity.Template; 61 import org.apache.velocity.VelocityContext; 62 import org.apache.velocity.app.VelocityEngine; 63 64 import com.thoughtworks.qdox.ant.AbstractQdoxTask; 65 import com.thoughtworks.qdox.model.AbstractJavaEntity; 66 import com.thoughtworks.qdox.model.DocletTag; 67 import com.thoughtworks.qdox.model.JavaClass; 68 import com.thoughtworks.qdox.model.JavaMethod; 69 import com.thoughtworks.qdox.model.JavaParameter; 70 import com.thoughtworks.qdox.model.Type; 71 72 /*** 73 * @author zsombor 74 * 75 * Created at 20:02:11 net.sf.bigyo.container.ant.RegistryGenerator 76 * Created on 2004.09.19. 77 * 78 */ 79 public class RegistryGenerator extends AbstractQdoxTask { 80 81 Main main; 82 83 String registryPath; 84 85 File outputDir; 86 87 boolean verbose = false; 88 89 Template mbeanImplTemplate; 90 Template mbeanTemplate; 91 Template beanWrapperTemplate; 92 Template factoryTemplate; 93 Template mbeanDescriptorTemplate; 94 95 Template pmMXTemplate; 96 97 boolean generateSource = false; 98 99 boolean generatePMX = false; 100 101 String rootRegistry = null; 102 103 /* 104 * (non-Javadoc) 105 * 106 * @see com.thoughtworks.qdox.ant.AbstractQdoxTask#execute() 107 */ 108 public void execute() throws BuildException { 109 BasicConfigurator.configure(); 110 111 generateSource = outputDir != null; 112 113 if (generateSource) { 114 log("source generating to " + outputDir); 115 VelocityEngine ve = new VelocityEngine(); 116 117 try { 118 Properties prop = new Properties(); 119 prop.setProperty("resource.loader", "classpath"); 120 prop.setProperty("classpath.resource.loader.class", 121 "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); 122 123 ve.init(prop); 124 mbeanTemplate = ve.getTemplate("net/sf/bigyo/container/ant/mbean.vm"); 125 beanWrapperTemplate = ve.getTemplate("net/sf/bigyo/container/ant/beanwrapper.vm"); 126 mbeanImplTemplate = ve.getTemplate("net/sf/bigyo/container/ant/mbeanimpl.vm"); 127 factoryTemplate = ve.getTemplate("net/sf/bigyo/container/ant/factory.vm"); 128 mbeanDescriptorTemplate = ve.getTemplate("net/sf/bigyo/container/ant/mbeandescriptor.vm"); 129 pmMXTemplate = ve.getTemplate("net/sf/bigyo/container/ant/mxtemplate.vm"); 130 131 132 } catch (Exception e) { 133 e.printStackTrace(); 134 throw new BuildException("Exception:" + e.getMessage(), e); 135 } 136 } else { 137 log("source not generated"); 138 } 139 140 main = new Main(); 141 142 super.execute(); 143 144 log("create registry at " + registryPath); 145 146 for (int i = 0; i < this.allClasses.size(); i++) { 147 JavaClass jc = (JavaClass) allClasses.get(i); 148 DocletTag tag = jc.getTagByName("bigyo-component"); 149 if (tag != null) { 150 parseClass(jc, tag); 151 } 152 } 153 154 try { 155 if (rootRegistry != null) 156 main.loadComponentRegistry(Kernel.createReader(rootRegistry)); 157 main.getRegistry().validateRegistry(); 158 main.getRegistry().storeRegistry(registryPath); 159 log("finished."); 160 } catch (CyclicDependencyException e) { 161 e.printStackTrace(); 162 throw new BuildException("Cyclic dependency error:" + e.getMessage(), e); 163 } catch (ContainerException e) { 164 e.printStackTrace(); 165 throw new BuildException("Container exception:" + e.getMessage(), e); 166 } catch (IOException e) { 167 e.printStackTrace(); 168 throw new BuildException("IO exception:" + e.getMessage(), e); 169 170 } 171 172 } 173 174 public void setRootRegistry(String path) { 175 log("registry " + path + " added"); 176 rootRegistry = path; 177 } 178 179 180 class ComponentInfo { 181 JavaClass jc; 182 ComponentDescription cd; 183 List publishedMethods; 184 185 /*** 186 * @param jc 187 * @param cd 188 */ 189 public ComponentInfo(JavaClass jc, ComponentDescription cd) { 190 super(); 191 publishedMethods = new ArrayList(); 192 this.jc = jc; 193 this.cd = cd; 194 } 195 196 public void addToPublish(JavaMethod method) { 197 publishedMethods.add(method); 198 } 199 200 /*** 201 * @return Returns the publishedMethods. 202 */ 203 public List getPublishedMethods() { 204 return publishedMethods; 205 } 206 207 /*** 208 * @return Returns the JavaClass . 209 */ 210 public JavaClass getJavaClass() { 211 return jc; 212 } 213 214 /*** 215 * @return Returns the ComponentDescription. 216 */ 217 public ComponentDescription getComponentDescription() { 218 return cd; 219 } 220 } 221 222 /*** 223 * @param jc 224 * @param tag 225 */ 226 private void parseClass(JavaClass jc, DocletTag tag) { 227 String componentName = tag.getValue(); 228 String type = getValue(jc, "bigyo-type", "singleton"); 229 log("found component : " + jc.getFullyQualifiedName()); 230 log(" component name:" + componentName); 231 if (componentName == null || "".equals(componentName.trim())) 232 throw new BuildException("component name is not specified in: " + jc.getFullyQualifiedName() 233 + ", missing tag: @bigyo-component my-component"); 234 if (verbose) 235 log(" type: " + type); 236 237 ComponentDescription cd = new ComponentDescription(componentName, jc.getFullyQualifiedName(), null, type); 238 239 ComponentInfo ci = new ComponentInfo(jc, cd); 240 241 DocletTag[] provides = jc.getTagsByName("bigyo-provide"); 242 for (int j = 0; j < provides.length; j++) { 243 if (verbose) 244 log(" provides:" + provides[j].getValue()); 245 cd.addProvideAlias(provides[j].getValue()); 246 } 247 248 DocletTag[] depends = jc.getTagsByName("bigyo-after"); 249 for (int j = 0; j < depends.length; j++) { 250 if (verbose) 251 log(" after :" + depends[j].getValue()); 252 cd.addDepend(depends[j].getValue(), ClassDependency.AFTER); 253 } 254 255 depends = jc.getTagsByName("bigyo-before"); 256 for (int j = 0; j < depends.length; j++) { 257 if (verbose) 258 log(" before :" + depends[j].getValue()); 259 cd.addDepend(depends[j].getValue(), ClassDependency.BEFORE); 260 } 261 262 depends = jc.getTagsByName("bigyo-depend"); 263 for (int j = 0; j < depends.length; j++) { 264 if (verbose) 265 log(" depend :" + depends[j].getValue()); 266 cd.addDepend(depends[j].getValue()); 267 } 268 269 DocletTag[] alias = jc.getTagsByName("bigyo-alias"); 270 for (int i=0;i<alias.length;i++) { 271 Map map = alias[i].getNamedParameterMap(); 272 273 for (Iterator keys= map.keySet().iterator();keys.hasNext();) { 274 String key = (String) keys.next(); 275 String value = ((String) map.get(key)).replace('-','$'); 276 if (verbose) 277 log(" alias :" + key+" -> "+value); 278 cd.setClassShortcut(key,value); 279 } 280 } 281 282 JavaClass configClass = null; 283 284 //System.out.println("methods:"+methods.length); 285 configClass = parseMethods(jc, ci); 286 JavaClass sup = jc.getSuperJavaClass(); 287 while (sup != null) { 288 log("parse super class:" + sup.getName()); 289 parseMethods(sup, ci); 290 sup = sup.getSuperJavaClass(); 291 } 292 createMBean(configClass, ci); 293 main.getRegistry().addComponentDescription(cd); 294 295 } 296 297 /*** 298 * @param jc 299 * @param ci 300 * @param configClass 301 * @return 302 */ 303 private JavaClass parseMethods(JavaClass jc, ComponentInfo ci) { 304 JavaClass configClass = null; 305 JavaMethod[] methods = jc.getMethods(); 306 for (int j = 0; j < methods.length; j++) { 307 JavaMethod m = methods[j]; 308 309 Type t = parseMethod(ci, m); 310 if (t != null) 311 configClass = t.getJavaClass(); 312 } 313 return configClass; 314 } 315 316 317 /*** 318 * @param generatePMX The generatePMX to set. 319 */ 320 public void setPMX(boolean generatePMX) { 321 this.generatePMX = generatePMX; 322 } 323 /*** 324 * @param cd 325 * @param m 326 */ 327 private Type parseMethod(ComponentInfo ci, JavaMethod m) { 328 ComponentDescription cd = ci.getComponentDescription(); 329 if (verbose) 330 log("method:" + m.getName() + " constructor:" + m.isConstructor()); 331 Type configType = null; 332 if (m.isConstructor() && (cd.getConfigClass() == null)) { 333 if (getValue(m, "bigyo-constructor") != null) { 334 JavaParameter[] params = m.getParameters(); 335 if (params.length > 0) { 336 configType = params[0].getType(); 337 if (verbose) 338 log(" config class:" + configType.getValue()); 339 cd.setConfigClass(configType.getValue()); 340 } else { 341 if (verbose) 342 log(" no-op constructor"); 343 } 344 } 345 } else { 346 String value = getValue(m, "bigyo-depend"); 347 if (value != null) { 348 if (verbose) 349 log(" dependency on:" + value + " [" + m.getName() + ']'); 350 cd.addDependSetter(value, m.getName()); 351 } 352 value = getValue(m, "bigyo-optional"); 353 if (value != null) { 354 if (verbose) 355 log(" optional dependency on:" + value + " [" + m.getName() + ']'); 356 cd.addOptionalDependSetter(value, m.getName()); 357 } 358 if (hasValue(m, "bigyo-start") && cd.getStart() == null) { 359 if (verbose) 360 log(" start method:" + m.getName()); 361 cd.setStart(m.getName()); 362 } 363 if (hasValue(m, "bigyo-stop") && cd.getStop() == null) { 364 if (verbose) 365 log(" stop method:" + m.getName()); 366 cd.setStop(m.getName()); 367 } 368 if (hasValue(m, "bigyo-publish")) { 369 if (verbose) 370 log(" published method:" + m.getName()); 371 ci.addToPublish(m); 372 } 373 } 374 return configType; 375 } 376 377 private String getValue(AbstractJavaEntity jc, String name) { 378 return getValue(jc, name, null); 379 } 380 381 private boolean hasValue(AbstractJavaEntity jc, String name) { 382 DocletTag tag = jc.getTagByName(name); 383 /* 384 * if (verbose) log("tag:"+tag+" "+jc+"-"+name); 385 */ 386 return tag != null; 387 } 388 389 private String getValue(AbstractJavaEntity jc, String name, String defValue) { 390 DocletTag tag = jc.getTagByName(name); 391 if (tag != null) 392 return tag.getValue(); 393 return defValue; 394 } 395 396 /*** 397 * @param registryPath 398 * The registryPath to set. 399 */ 400 public void setRegistryPath(String registryPath) { 401 this.registryPath = registryPath; 402 } 403 404 /*** 405 * @param verbose 406 * The verbose to set. 407 */ 408 public void setVerbose(boolean verbose) { 409 this.verbose = verbose; 410 } 411 412 /*** 413 * @param outputDir 414 * The outputDir to set. 415 */ 416 public void setOutputDirectory(File outputDir) { 417 this.outputDir = outputDir; 418 } 419 420 void createMBean(JavaClass jc, ComponentInfo ci) { 421 JavaClass serviceClass = ci.getJavaClass(); 422 423 if (!generateSource) 424 return; 425 VelocityContext context = new VelocityContext(); 426 log("create mbean for " + serviceClass.getPackage() + ':' + serviceClass.getName()); 427 if (jc != null) { 428 context.put("javaclass", jc); 429 context.put("attributes", jc.getBeanProperties()); 430 context.put("methods",jc.getMethods(false)); 431 context.put("wrapperName", Constants.getWrapperName(jc.getName())); 432 context.put("factoryName", Constants.getFactoryName(jc.getName())); 433 } 434 log("service class:" + serviceClass.getName()); 435 context.put("description", ci.getComponentDescription()); 436 context.put("mbeanName", Constants.getMBeanName(serviceClass.getName())); 437 context.put("mbeanImplName", Constants.getMBeanImplName(serviceClass.getName())); 438 context.put("mbeanDescriptor", Constants.getMBeanDescriptor(serviceClass.getName())); 439 context.put("serviceclass", serviceClass); 440 context.put("mxClass",Constants.getPMX(serviceClass.getName())); 441 442 context.put("publish", ci.getPublishedMethods()); 443 444 try { 445 // create necessary directories 446 File serviceOutput = new File(outputDir, serviceClass.getPackage().replace('.', File.separatorChar)); 447 serviceOutput.mkdirs(); 448 449 // create MBeanImpl class 450 mergeTemplate(context, mbeanImplTemplate, serviceOutput, Constants.getMBeanImplName(serviceClass.getName()) 451 + ".java"); 452 453 // create MBean interface 454 mergeTemplate(context, mbeanTemplate, serviceOutput, Constants.getMBeanName(serviceClass.getName()) 455 + ".java"); 456 457 // create MBean Descriptor 458 mergeTemplate(context, mbeanDescriptorTemplate, serviceOutput, Constants.getMBeanDescriptor(serviceClass 459 .getName()) 460 + ".java"); 461 462 if (generatePMX) { 463 mergeTemplate(context, pmMXTemplate, serviceOutput, Constants.getPMX(serviceClass.getName())+".java"); 464 } 465 // create necessary directories 466 if (jc != null) { 467 File output = new File(outputDir, jc.getPackage().replace('.', File.separatorChar)); 468 output.mkdirs(); 469 // create Bean wrapper 470 mergeTemplate(context, beanWrapperTemplate, output, Constants.getWrapperName(jc.getName()) + ".java"); 471 } 472 // create Bean wrapper 473 //if (!"singleton".equals(cd.getType())) { 474 //mergeTemplate(context,factoryTemplate,output,jc.getName()+"Factory.java"); 475 //} 476 477 } catch (Exception rnf) { 478 rnf.printStackTrace(); 479 throw new RuntimeException("Exception:" + rnf.getMessage(), rnf); 480 } 481 482 } 483 484 void mergeTemplate(VelocityContext context, Template t, File output, String fileName) throws Exception { 485 BufferedWriter w = new BufferedWriter(new FileWriter(new File(output, fileName))); 486 t.merge(context, w); 487 w.close(); 488 489 } 490 491 }

This page was automatically generated by Maven